package fr.cephb.joperon.core.iterator;

import java.util.Iterator;

import fr.cephb.util.CloseableIterator;

/**
 * Iterator iterating from a given index for a given number of items
 * @author lindenb
 *
 * @param <T> type of delegate Iterator
 */
public class FromToIterator<T>
	extends AbstractIterator<T> {
	private int start=0;
	private int length=Integer.MAX_VALUE;
	private int index=0;
	private Iterator<T> delegate=null;
	/**
	 * Constructor
	 * @param delegate delegate iterator
	 * @param start start index
	 * @param length number of items
	 */
	public FromToIterator(Iterator<T> delegate,int start,int length)
		{
		this.delegate=delegate;
		this.index=0;
		this.start=start;
		this.length=length;
		}
	
	private void closeDelegate()
		{
		if(this.delegate==null) return;
		if(this.delegate instanceof CloseableIterator) CloseableIterator.class.cast(this.delegate).close();
		this.delegate=null;
		}
	
	@Override
	public boolean hasNext()
		{
		if(delegate==null) return false;
		while(index< start)
			{
			if(!delegate.hasNext()) break;
			delegate.next();
			++index;
			}
		if(index<start)
			{
			closeDelegate();
			return false;
			}
		boolean b= this.delegate.hasNext();
		if(!b) closeDelegate();
		return b;
		}
	
	@Override
	public T next()
		{
		if(this.delegate==null) throw new IllegalStateException("this.delegate==null");
		T value= this.delegate.next();
		++index;
		if(index>=(start+length)) closeDelegate();
		return value;
		}

}
